package tests;

import static org.junit.Assert.*;

import java.io.StringReader;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import parsing.CritterParser;
import parsing.productions.*;
import world.Critter;
import world.CritterWorld;
import world.Hex;
import world.Location;

public class NumberNodeTests{

	private static CritterParser parser;
	private static CritterWorld world;
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		parser = new CritterParser();
		world = new CritterWorld("constants.txt");
	}

	@Before
	public void setUp() throws Exception {
	}

	@Test
	public void atomTest() {
		//number type
		Program program = parser.parse(new StringReader(
				"4 > 5 --> left;"));
		AbstractNode node = program;
		for(int i = 0; i < 7; i++)
			node = node.getChildren().get(0);
		Atom atom = (Atom) node;
		assertEquals("The Atom's value was not 4 as expected", 4, (int) atom.getValue(null));
		
		//mem type
		program = parser.parse(new StringReader(
				"mem[4] > 5 --> left;"));
		node = program;
		for(int i = 0; i < 7; i++)
			node = node.getChildren().get(0);
		atom = (Atom) node;
		Critter crit = new Critter(world, new Hex(world, new Location(world, 0, 0)), 7, 0, 0);
		assertEquals("The Atom's value was not the initial energy of a Critter",
				world.INITIAL_ENERGY, (int) atom.getValue(crit));
		
		//negative index for mem and (term) type
		program = parser.parse(new StringReader(
				"mem[(1-5) + 0] > 5 --> left;"));
		node = program;
		for(int i = 0; i < 7; i++)
			node = node.getChildren().get(0);
		atom = (Atom) node;
		crit = new Critter(world, new Hex(world, new Location(world, 0, 0)), 7, 0, 0);
		assertEquals("The Atom's value was not the initial energy of a Critter",
				world.INITIAL_ENERGY, (int) atom.getValue(crit));
		
		//sensor type
		program = parser.parse(new StringReader(
				"food > 5 --> left;"));
		node = program;
		for(int i = 0; i < 7; i++)
			node = node.getChildren().get(0);
		atom = (Atom) node;
		Hex hex = world.getHex(new Location(world, 0, 0));
		hex.putFood(150);
		crit = new Critter(world, hex, 7, 0, 0);
		assertEquals("The Atom's value was not 1 (food value for the hex the critter is on)",
				1, (int) atom.getValue(crit));
	}

	@Test
	public void factorTest() {
		Program program = parser.parse(new StringReader(
				"4 * 3 > 5 --> left;"));
		AbstractNode node = program;
		for(int i = 0; i < 6; i++)
			node = node.getChildren().get(0);
		Factor factor = (Factor) node;
		assertEquals("The Factor's value was not 12 as expected", 12, (int) factor.getValue(null));
	}

	@Test
	public void termTest() {
		Program program = parser.parse(new StringReader(
				"2 + 4 * 3 > 5 --> left;"));
		AbstractNode node = program;
		for(int i = 0; i < 5; i++)
			node = node.getChildren().get(0);
		Term term = (Term) node;
		assertEquals("The Term's value was not 14 as expected", 14, (int) term.getValue(null));
	}

}
